package com.easyadmin.pro.common.page;

import com.easyadmin.pro.common.vo.BaseQuery;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * packageName com.easyadmin.pro.common.page
 *
 * @author 骑着蚂蚁去上天
 * @version JDK 17
 * @className Pageable
 * @date 2024/4/10
 * @description 分页工具
 */
public class Pageable {


    /**
     * 内存分页
     * @param records 待分页数据
     * @param pageIndex 野马川镇
     * @param pageSize 条数
     * @return
     * @param <T>
     */
    public static <T> List<T> of(List<T> records, int pageIndex, int pageSize) {
        if (records==null) {
            return Collections.emptyList();
        }
        int totalCount = records.size();
        int remainder = totalCount % pageSize;
        int pageCount = (remainder > 0) ? totalCount/pageSize + 1 : totalCount/pageSize;
        if (remainder == 0) {
            return records.stream().skip((pageIndex - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        } else {
            if (pageIndex == pageCount) {
                return records.stream().skip((pageIndex - 1) * pageSize).limit(totalCount).collect(Collectors.toList());
            } else {
                return records.stream().skip((pageIndex - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
            }
        }
    }

    /**
     * 内存分页
     *
     * @param request  分页参数
     * @param records  待分页的数据
     * @return 分页数据 {@link BaseQuery}
     */
    public static <T> PageResponse<T> of(BaseQuery request, List<T> records) {
        return PageResponse.page(new PageInfo<T>(of(records, request.getPageNo(), request.getPageSize())));
    }


    /**
     * 物理分页
     *
     * @param request 分页参数
     * @return 分页数据 {@link BaseQuery}
     */
    public static <T> PageResponse of(BaseQuery request, Record record){
        PageHelper.startPage(request.getPageNo(),request.getPageSize());
        return PageResponse.page(new PageInfo(record.invoke()));
    }

    /**
     * 内部类
     *
     * 用于分页数据的来源实现
     * */
    public interface Record<T> {
        /**
         * 数据获取
         * @return
         */
        List<T> invoke();
    }
}